﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using HierarchicalClustering;

namespace TextMining
{
    public class DocumentsSet   // Set containing dataset's words and documents
    {
        // words are kept in a map
        private SortedList<string, Word> _words = new SortedList<string, Word>();
        // documents are kept in a linked list. They are actually the initial clusters
        private LinkedList<Cluster> _clusters = new LinkedList<Cluster>();

        public Word AddWord(string name)   // add word
        {
            name = name.ToLower();

            if (_words.ContainsKey(name) == true)  // don't add a word which is already in
                return _words[name];   // return word

            Word word = new Word(name);  // add new word
            _words.Add(name, word);

            return word;   // return word
        }

        public Word GetWord(string name)
        {
            name = name.ToLower();
            return _words[name];
        }

        public IEnumerable<Word> GetWords()   // get all words
        {
            return _words.Values;
        }

        // remove a percentage of words sorted by the tf-idf method
        public void RemoveLessImportant(int documents, double percentage)
        {
            if (percentage < 0 || percentage > 100)   // wrong number of percentage
                return;

            int count = (int)(percentage * _words.Count / 100);  // number of words to remove

            var query = from word in GetWords()   // get words to remove
                        orderby word.TfIdfValue(documents) ascending
                        select word;

            foreach (Word word in query.Take(count))
                word.IsImportant = false;   // set those words as not important
        }

        public void AddDocument(Document document)   // add a new document
        {
            Cluster cluster = new Cluster(_clusters.Count + 1, document);
            _clusters.AddLast(cluster);
        }

        public LinkedList<Cluster> GetTrainingSample ( double samplePercentage)
        {  // get a specific set of the initial clusters
            int sample = (int) (_clusters.Count * samplePercentage / 100);   // number of clusters to get

            LinkedList<Cluster> list = new LinkedList<Cluster>();

            for (int i = 0; i < sample; i++)    // get those clusters
                list.AddLast(_clusters.ElementAt(i));

            return list;
        }

        public LinkedList<Cluster> GetTrainingSample()   // get the whole set of initial clusters
        {
            return _clusters;
        }

        public IEnumerable<Cluster> GetRestClusters( double samplePercentage)
        {    // get clusters that were not included in the training sample
           int sample = (int) (_clusters.Count * samplePercentage / 100);   // number of clusters to skip

           LinkedList<Cluster> rest = new LinkedList<Cluster>();

           for (int i = sample; i < _clusters.Count; i++)  // get the rest clusters
           {
               rest.AddLast((Cluster)_clusters.ElementAt(i));
           }

           return (IEnumerable<Cluster>)rest;
        }
    }
}
